﻿/*
 * File: MenuItem.cs
 * Author: Gourav Das
 * Purpose: Represents a single Menu Item
 * Created: April 30 2011
 * Copyright: Gourav Das, 2011
 */

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using _22yards._2D;
using _22yards.Scenes;
using _22yards.Core;

namespace _22yards.Scenes.Helpers
{

    /// <summary>
    /// Scene Helper class that represents a single entry in a Menu. 
    /// </summary>
    class MenuItem
    {

        /// <summary>
        /// Gets or sets a value indicating whether [display on left corner].
        /// </summary>
        /// <value>
        /// 	<c>true</c> if [display on left corner]; otherwise, <c>false</c>.
        /// </value>
        public bool DisplayOnLeftCorner { get; set; }
        /// <summary>
        /// Gets or sets a value indicating whether [display on right corner].
        /// </summary>
        /// <value>
        /// 	<c>true</c> if [display on right corner]; otherwise, <c>false</c>.
        /// </value>
        public bool DisplayOnRightCorner { get; set; }

        /// <summary>
        /// Gets or sets the menu item ID.
        /// </summary>
        /// <value>
        /// The menu item ID.
        /// </value>
        public int MenuItemID { get; set; }

        /// <summary>
        /// Gets or sets the boundin box.
        /// </summary>
        /// <value>
        /// The boundin box.
        /// </value>
        public MenuBoundingBox boundinBox{ get; set; }

        /// <summary>
        /// The text rendered for this entry.
        /// </summary>
        public string Menutext { get; set; }

        /// <summary>
        /// Tracks a fading selection effect on the entry. It transitions out of the selection effect when they are deselected.
        /// </summary>
        float selectionFade;

        /// <summary>
        /// Gets or sets the position at which to draw this menu entry.
        /// </summary>
        public Vector2 Position { get; set; }

        /// <summary>
        /// Event raised when the menu item is selected.
        /// </summary>
        public event EventHandler<PlayerIndexEventArgs> Selected;


        /// <summary>
        /// Method for raising the Selected event.
        /// </summary>
        /// <param name="_playerIndex">Index of the player.</param>
        protected internal virtual void OnSelectEntry(PlayerIndex _playerIndex)
        {
            if (Selected != null)
                Selected(this, new PlayerIndexEventArgs(_playerIndex));
        }


        /// <summary>
        /// Constructs a new menu Item with the specified text.
        /// </summary>
        /// <param name="_text">The text.</param>
        /// <param name="ID">The ID.</param>
        /// <param name="displayLeftCorner">if set to <c>true</c> [display left corner].</param>
        /// <param name="displayRightCorner">if set to <c>true</c> [display right corner].</param>
        public MenuItem(string _text, int ID, bool displayLeftCorner=false, bool displayRightCorner=false)
        {
            this.Menutext = _text;
            this.MenuItemID = ID;
            boundinBox = new MenuBoundingBox();
            DisplayOnLeftCorner = displayLeftCorner;
            DisplayOnRightCorner = displayRightCorner;

            if (DisplayOnLeftCorner && DisplayOnRightCorner) { DisplayOnLeftCorner = false; DisplayOnRightCorner = false; }


        }


        /// <summary>
        /// Updates the menu entry.
        /// </summary>
        /// <param name="_scene">The _scene.</param>
        /// <param name="_isSelected">if set to <c>true</c> [_is selected].</param>
        /// <param name="_gameTime">The _game time.</param>
        public virtual void Update(BaseMenuScene _scene, bool _isSelected, GameTime _gameTime)
        {

            // When the menu selection changes, entries gradually fade between
            // their selected and deselected appearance, rather than instantly
            // popping to the new state.
            float fadeSpeed = (float)_gameTime.ElapsedGameTime.TotalSeconds * 4;

            if (_isSelected)
                selectionFade = Math.Min(selectionFade + fadeSpeed, 1);
            else
                selectionFade = Math.Max(selectionFade - fadeSpeed, 0);
        }


        /// <summary>
        /// Draws the menu entry in default pulsating manner. This can be overridden to customize the appearance.
        /// </summary>
        /// <param name="_scene">The _scene.</param>
        /// <param name="_isSelected">if set to <c>true</c> [_is selected].</param>
        /// <param name="_gameTime">The _game time.</param>
        public virtual void Draw(BaseMenuScene _scene, bool _isSelected, GameTime _gameTime)
        {

            // Draw the selected entry in red, otherwise white.
            Color color = _isSelected ? Color.Red : Color.White;

            // Pulsate the size of the selected menu entry.
            double time = _gameTime.TotalGameTime.TotalSeconds;
            float pulsate = (float)Math.Sin(time * 6) + 1;
            float scale = 1 + pulsate * 0.05f * selectionFade;

            // Modify the alpha to fade text out during transitions.
            color *= _scene.TransitionAlpha;

            // Draw text, centered on the middle of each line.
            SceneEngine sceneEngine = _scene.sceneEngine;

            Vector2 origin = new Vector2(0, sceneEngine.TxtNFont.spFontPescadero.LineSpacing / 2);

            sceneEngine.SpriteBatch.DrawString(sceneEngine.TxtNFont.spFontPescadero, Menutext, Position, color, 0,
                                   origin, scale, SpriteEffects.None, 0);
            boundinBox.Position= Position;
        }


        /// <summary>
        /// Gets the height of this menu item.
        /// </summary>
        public virtual int GetHeight(BaseMenuScene _scene)
        {
            return _scene.sceneEngine.TxtNFont.spFontPescadero.LineSpacing;
        }


        /// <summary>
        /// Gets the width of the Menu item.
        /// </summary>
        public virtual int GetWidth(BaseMenuScene _scene)
        {
            return (int)_scene.sceneEngine.TxtNFont.spFontPescadero.MeasureString(Menutext).X;
        }

    }
}
